use TextArea instead of TextEdit for share note field
authorJyrki Gadinger <nilsding@nilsding.org>
Thu, 13 Feb 2025 13:14:30 +0000 (14:14 +0100)
committerbackportbot[bot] <backportbot[bot]@users.noreply.github.com>
Fri, 14 Feb 2025 13:23:14 +0000 (13:23 +0000)
it's already styled properly as it's part of Qt Quick Controls, **and**
it allows for a placeholder text!

also changed the logic for displaying the text field a bit ...

Fixes #7847

Signed-off-by: Jyrki Gadinger <nilsding@nilsding.org>
resources.qrc
src/gui/filedetails/NCInputTextArea.qml [new file with mode: 0644]
src/gui/filedetails/NCInputTextEdit.qml [deleted file]
src/gui/filedetails/ShareDelegate.qml
src/gui/filedetails/ShareDetailsPage.qml
src/gui/filedetails/ShareView.qml
src/gui/filedetails/sharemodel.cpp
src/gui/filedetails/sharemodel.h
test/testsharemodel.cpp

index 715f7cf8174bc32025ce9064d375c6f8f3f469d5..6036fa0e1bff0ad998be15c9bc4e252fa32679f4 100644 (file)
@@ -13,7 +13,7 @@
         <file>src/gui/filedetails/FileDetailsWindow.qml</file>
         <file>src/gui/filedetails/FileTag.qml</file>
         <file>src/gui/filedetails/NCInputDateField.qml</file>
-        <file>src/gui/filedetails/NCInputTextEdit.qml</file>
+        <file>src/gui/filedetails/NCInputTextArea.qml</file>
         <file>src/gui/filedetails/NCInputTextField.qml</file>
         <file>src/gui/filedetails/NCTabButton.qml</file>
         <file>src/gui/filedetails/ShareeDelegate.qml</file>
diff --git a/src/gui/filedetails/NCInputTextArea.qml b/src/gui/filedetails/NCInputTextArea.qml
new file mode 100644 (file)
index 0000000..d3e917f
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 by Claudio Cambra <claudio.cambra@nextcloud.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+
+import com.nextcloud.desktopclient
+import Style
+
+TextArea {
+    id: root
+
+    readonly property color accentColor: palette.highlight
+    readonly property color secondaryColor: palette.placeholderText
+    readonly property alias submitButton: submitButton
+
+    // no implicitHeight here -- let the textarea take as much as it needs
+    // otherwise it will cut off some text vertically on multi-line strings...
+
+    selectByMouse: true
+    rightPadding: submitButton.width
+
+    wrapMode: TextEdit.Wrap
+
+    Button {
+        id: submitButton
+
+        anchors.bottom: root.bottom
+        anchors.right: root.right
+        anchors.margins: 1
+
+        width: height
+        height: parent.height
+
+        flat: true
+        icon.source: "image://svgimage-custom-color/confirm.svg" + "/" + root.secondaryColor
+        icon.color: hovered && enabled ? UserModel.currentUser.accentColor : root.secondaryColor
+
+        enabled: root.text !== ""
+
+        onClicked: root.editingFinished()
+    }
+}
diff --git a/src/gui/filedetails/NCInputTextEdit.qml b/src/gui/filedetails/NCInputTextEdit.qml
deleted file mode 100644 (file)
index 24dacdd..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2022 by Claudio Cambra <claudio.cambra@nextcloud.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-
-import com.nextcloud.desktopclient
-import Style
-
-TextEdit {
-    id: root
-
-    readonly property color accentColor: palette.highlight
-    readonly property color secondaryColor: palette.placeholderText
-    readonly property alias submitButton: submitButton
-
-    clip: true
-    textMargin: Style.smallSpacing
-    wrapMode: TextEdit.Wrap
-    selectByMouse: true
-    height: Math.max(Style.talkReplyTextFieldPreferredHeight, contentHeight)
-
-    Rectangle {
-        id: textFieldBorder
-        anchors.fill: parent
-        radius: Style.trayWindowRadius
-        border.width: Style.normalBorderWidth
-        border.color: root.activeFocus ? root.accentColor : root.secondaryColor
-        color: palette.base
-        z: -1
-    }
-
-    Button {
-        id: submitButton
-
-        anchors.bottom: root.bottom
-        anchors.right: root.right
-        anchors.margins: 1
-
-        width: height
-        height: parent.height
-
-        flat: true
-        icon.source: "image://svgimage-custom-color/confirm.svg" + "/" + root.secondaryColor
-        icon.color: hovered && enabled ? UserModel.currentUser.accentColor : root.secondaryColor
-
-        enabled: root.text !== ""
-
-        onClicked: root.editingFinished()
-    }
-}
-
index 895153fba632ac06f1f44d3c66939b5bf9ad1b9a..d6bb454a94090a6e954895d66f7a859d3d6a67dd 100644 (file)
@@ -38,7 +38,6 @@ GridLayout {
     signal toggleAllowResharing(bool enable)
     signal togglePasswordProtect(bool enable)
     signal toggleExpirationDate(bool enable)
-    signal toggleNoteToRecipient(bool enable)
     signal permissionModeChanged(int permissionMode)
 
     signal setLinkShareLabel(string label)
@@ -252,7 +251,6 @@ GridLayout {
                     onToggleHideDownload: root.toggleHideDownload(enable)
                     onTogglePasswordProtect: root.togglePasswordProtect(enable)
                     onToggleExpirationDate: root.toggleExpirationDate(enable)
-                    onToggleNoteToRecipient: root.toggleNoteToRecipient(enable)
                     onPermissionModeChanged: root.permissionModeChanged(permissionMode)
 
                     onSetLinkShareLabel: root.setLinkShareLabel(label)
index 79897f73f44bdeb91c365b9edb19f46882eb26fa..8035b40d9d195b47275279051a31a4cd46c7af71 100644 (file)
@@ -87,7 +87,6 @@ Page {
     readonly property bool isFolderItem: shareModelData.sharedItemType === ShareModel.SharedItemTypeFolder
     readonly property bool isEncryptedItem: shareModelData.sharedItemType === ShareModel.SharedItemTypeEncryptedFile || shareModelData.sharedItemType === ShareModel.SharedItemTypeEncryptedFolder || shareModelData.sharedItemType === ShareModel.SharedItemTypeEncryptedTopLevelFolder
 
-    property bool waitingForNoteEnabledChange: false
     property bool waitingForExpireDateEnabledChange: false
     property bool waitingForPasswordProtectEnabledChange: false
     property bool waitingForExpireDateChange: false
@@ -101,7 +100,7 @@ Page {
     }
 
     function resetNoteField() {
-        noteTextEdit.text = note;
+        noteTextArea.text = note;
         waitingForNoteChange = false;
     }
 
@@ -133,7 +132,7 @@ Page {
 
     function resetNoteEnabledField() {
         noteEnabledMenuItem.checked = noteEnabled;
-        waitingForNoteEnabledChange = false;
+        waitingForNoteChange = false;
     }
 
     function resetExpireDateEnabledField() {
@@ -662,16 +661,18 @@ Page {
                 checkable: true
                 checked: root.noteEnabled
                 text: qsTr("Note to recipient")
-                enabled: !root.waitingForNoteEnabledChange
+                enabled: !root.waitingForNoteChange
 
                 onClicked: {
-                    root.toggleNoteToRecipient(checked);
-                    root.waitingForNoteEnabledChange = true;
+                    if (!checked && root.note !== "") {
+                        root.setNote("");
+                        root.waitingForNoteChange = true;
+                    }
                 }
 
                 NCBusyIndicator {
                     anchors.fill: parent
-                    visible: root.waitingForNoteEnabledChange
+                    visible: root.waitingForNoteChange && !noteEnabledMenuItem.checked
                     running: visible
                     z: 1
                 }
@@ -682,7 +683,7 @@ Page {
                 height: visible ? implicitHeight : 0
                 spacing: scrollContentsColumn.indicatorSpacing
 
-                visible: root.noteEnabled
+                visible: noteEnabledMenuItem.checked
 
                 Image {
                     Layout.preferredWidth: scrollContentsColumn.indicatorItemWidth
@@ -697,27 +698,25 @@ Page {
                     sourceSize.height: scrollContentsColumn.rowIconWidth
                 }
 
-                NCInputTextEdit {
-                    id: noteTextEdit
+                NCInputTextArea {
+                    id: noteTextArea
 
                     Layout.fillWidth: true
-                    height: visible ? Math.max(Style.talkReplyTextFieldPreferredHeight, contentHeight) : 0
+                    // no height here -- let the textarea figure it out how much it needs
                     submitButton.height: Math.min(Style.talkReplyTextFieldPreferredHeight, height - 2)
 
                     text: root.note
-                    enabled: root.noteEnabled &&
-                             !root.waitingForNoteChange &&
-                             !root.waitingForNoteEnabledChange
+                    placeholderText: qsTr("Enter a note for the recipient")
+                    enabled: noteEnabledMenuItem.checked && !root.waitingForNoteChange
 
-                    onEditingFinished: if(text !== root.note) {
+                    onEditingFinished: if (text !== "" && text !== root.note) {
                         root.setNote(text);
                         root.waitingForNoteChange = true;
                     }
 
                     NCBusyIndicator {
                         anchors.fill: parent
-                        visible: root.waitingForNoteChange ||
-                                 root.waitingForNoteEnabledChange
+                        visible: root.waitingForNoteChange && noteEnabledMenuItem.checked
                         running: visible
                         z: 1
                     }
index 51bbb891a88974fc87a41d5f39651022f0aa4da9..1b7b9ca7de067cb5c2eb1fb096dfe3426d40fd95 100644 (file)
@@ -263,7 +263,6 @@ ColumnLayout {
                     onToggleHideDownload: shareModel.toggleHideDownloadFromQml(model.share, enable)
                     onTogglePasswordProtect: shareModel.toggleSharePasswordProtectFromQml(model.share, enable)
                     onToggleExpirationDate: shareModel.toggleShareExpirationDateFromQml(model.share, enable)
-                    onToggleNoteToRecipient: shareModel.toggleShareNoteToRecipientFromQml(model.share, enable)
                     onPermissionModeChanged: shareModel.changePermissionModeFromQml(model.share, permissionMode)
 
                     onSetLinkShareLabel: shareModel.setLinkShareLabelFromQml(model.share, label)
index e3be7122aea610b118875b24cf5762f74db774b9..c23ed0b05aeb3767eda9198ded1b28aea6db172c 100644 (file)
@@ -1088,26 +1088,6 @@ void ShareModel::toggleShareExpirationDateFromQml(const QVariant &share, const b
     toggleShareExpirationDate(ptr, enable);
 }
 
-void ShareModel::toggleShareNoteToRecipient(const SharePtr &share, const bool enable) const
-{
-    if (share.isNull()) {
-        return;
-    }
-
-    const QString note = enable ? tr("Enter a note for the recipient") : QString();
-    if (const auto linkShare = share.objectCast<LinkShare>()) {
-        linkShare->setNote(note);
-    } else if (const auto userGroupShare = share.objectCast<UserGroupShare>()) {
-        userGroupShare->setNote(note);
-    }
-}
-
-void ShareModel::toggleShareNoteToRecipientFromQml(const QVariant &share, const bool enable) const
-{
-    const auto ptr = share.value<SharePtr>();
-    toggleShareNoteToRecipient(ptr, enable);
-}
-
 void ShareModel::changePermissionModeFromQml(const QVariant &share, const OCC::ShareModel::SharePermissionsMode permissionMode)
 {
     const auto sharePtr = share.value<SharePtr>();
index 12b262bde7a5a00a295d2c07024b1c042f21acb6..c40329b3cf3b3dd3e019acc8b29386cbe4c580da 100644 (file)
@@ -190,8 +190,6 @@ public slots:
     void toggleSharePasswordProtectFromQml(const QVariant &share, const bool enable);
     void toggleShareExpirationDate(const OCC::SharePtr &share, const bool enable) const;
     void toggleShareExpirationDateFromQml(const QVariant &share, const bool enable) const;
-    void toggleShareNoteToRecipient(const OCC::SharePtr &share, const bool enable) const;
-    void toggleShareNoteToRecipientFromQml(const QVariant &share, const bool enable) const;
     void changePermissionModeFromQml(const QVariant &share, const OCC::ShareModel::SharePermissionsMode permissionMode);
 
     void setLinkShareLabel(const QSharedPointer<OCC::LinkShare> &linkShare, const QString &label) const;
index 1385dc73dc06c8b7ffa76eff40959a6a9a2a7c4c..c1e92bba66cb6fe092ccb55df989d6b862f07660 100644 (file)
@@ -820,7 +820,7 @@ private slots:
         helper.resetTestData();
 
         // Test with an existing link share.
-        // This one has a pre-existing password
+        // This one has a pre-existing note
         helper.appendShareReplyData(_testLinkShareDefinition);
         QCOMPARE(helper.shareCount(), 1);
 
@@ -844,7 +844,7 @@ private slots:
         const auto linkSharePtr = sharePtr.dynamicCast<LinkShare>(); // Need to connect to signal
         QSignalSpy noteSet(linkSharePtr.data(), &LinkShare::noteSet);
 
-        model.toggleShareNoteToRecipient(sharePtr, false);
+        model.setShareNote(sharePtr, QStringLiteral(""));
         QVERIFY(noteSet.wait(3000));
         QCOMPARE(shareIndex.data(ShareModel::NoteEnabledRole).toBool(), false);
 
@@ -852,7 +852,7 @@ private slots:
         model.setShareNote(sharePtr, note);
         QVERIFY(noteSet.wait(3000));
         QCOMPARE(shareIndex.data(ShareModel::NoteEnabledRole).toBool(), true);
-        // The model stores the recently set password.
+        // The model stores the recently set note.
         // We want to present the user with it in the UI while the model is alive
         QCOMPARE(shareIndex.data(ShareModel::NoteRole).toString(), note);
     }